package com.ilop.sthome.utils.system;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import androidx.annotation.RequiresPermission;

import android.telephony.TelephonyManager;
import android.util.Log;

import com.ilop.sthome.data.enums.NetworkType;

import java.util.List;

/**
 * @author skygge
 * @Date on 2020-02-25.
 * GitHub：javofxu@github.com
 * email：skygge@yeah.net
 * description：网络判断
 */
public class NetWorkUtil {
    private static final String TAG = "NetWorkUtil";
    public static volatile NetWorkUtil instance;

    /** 没有网络 */
    private static final int NETWORK_TYPE_INVALID = 0;
    /** 3G和3G以上网络，或统称为快速网络 */
    private static final int NETWORK_TYPE_3G = 3;
    /** wifi网络 */
    private static final int NETWORK_TYPE_WIFI = 4;

    public static NetWorkUtil getInstance() {
        if (instance == null){
            synchronized (NetWorkUtil.class){
                instance = new NetWorkUtil();
            }
        }
        return instance;
    }

    /**
     * 开启或关闭Wi-Fi
     */
    public boolean changeWifiState(Context mContext){
        WifiManager mManager = (WifiManager) mContext.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        assert mManager != null;
        switch (mManager.getWifiState()) {
            case WifiManager.WIFI_STATE_DISABLED:
                Log.i(TAG, "changeWifiState: wifi关闭状态");
                boolean isOpen = mManager.setWifiEnabled(true);
                Log.i(TAG, "changeWifiState: " + isOpen);
                return isOpen;
            case WifiManager.WIFI_STATE_ENABLED:
                Log.i(TAG, "changeWifiState: wifi打开状态");
                boolean isClose = mManager.setWifiEnabled(false);
                Log.i(TAG, "changeWifiState: " + isClose);
                return isClose;
            case WifiManager.WIFI_STATE_DISABLING:
                Log.i(TAG, "changeWifiState: wifi关闭中");
                return true;
            case WifiManager.WIFI_STATE_ENABLING:
                Log.i(TAG, "changeWifiState: wifi打开中");
                return true;
            case WifiManager.WIFI_STATE_UNKNOWN:
                Log.i(TAG, "changeWifiState: wifi状态不识别");
                return false;
        }
        return false;
    }

    /**
     * 获取当前网络类型
     * 需添加权限 {@code <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>}
     */
    @RequiresPermission("android.permission.ACCESS_NETWORK_STATE")
    public NetworkType getNetworkType(Context context) {
        NetworkType netType = NetworkType.NETWORK_NO;
        NetworkInfo info = getActiveNetworkInfo(context);
        if (info != null && info.isAvailable()) {

            if (info.getType() == ConnectivityManager.TYPE_WIFI) {
                netType = NetworkType.NETWORK_WIFI;
            } else if (info.getType() == ConnectivityManager.TYPE_MOBILE) {
                switch (info.getSubtype()) {

                    case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
                    case TelephonyManager.NETWORK_TYPE_EVDO_A:
                    case TelephonyManager.NETWORK_TYPE_UMTS:
                    case TelephonyManager.NETWORK_TYPE_EVDO_0:
                    case TelephonyManager.NETWORK_TYPE_HSDPA:
                    case TelephonyManager.NETWORK_TYPE_HSUPA:
                    case TelephonyManager.NETWORK_TYPE_HSPA:
                    case TelephonyManager.NETWORK_TYPE_EVDO_B:
                    case TelephonyManager.NETWORK_TYPE_EHRPD:
                    case TelephonyManager.NETWORK_TYPE_HSPAP:
                        netType = NetworkType.NETWORK_3G;
                        break;

                    case TelephonyManager.NETWORK_TYPE_LTE:
                    case TelephonyManager.NETWORK_TYPE_IWLAN:
                        netType = NetworkType.NETWORK_4G;
                        break;

                    case TelephonyManager.NETWORK_TYPE_GSM:
                    case TelephonyManager.NETWORK_TYPE_GPRS:
                    case TelephonyManager.NETWORK_TYPE_CDMA:
                    case TelephonyManager.NETWORK_TYPE_EDGE:
                    case TelephonyManager.NETWORK_TYPE_1xRTT:
                    case TelephonyManager.NETWORK_TYPE_IDEN:
                        netType = NetworkType.NETWORK_2G;
                        break;
                    default:
                        String subtypeName = info.getSubtypeName();
                        if (subtypeName.equalsIgnoreCase("TD-SCDMA")
                                || subtypeName.equalsIgnoreCase("WCDMA")
                                || subtypeName.equalsIgnoreCase("CDMA2000")) {
                            netType = NetworkType.NETWORK_3G;
                        } else {
                            netType = NetworkType.NETWORK_UNKNOWN;
                        }
                        break;
                }
            } else {
                netType = NetworkType.NETWORK_UNKNOWN;
            }
        }
        return netType;
    }

    @RequiresPermission("android.permission.ACCESS_NETWORK_STATE")
    private NetworkInfo getActiveNetworkInfo(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (cm != null) {
            return cm.getActiveNetworkInfo();
        }
        return null;
    }

    /**
     * 获取WI-FI的SSId
     * @return SSId
     */
    public String getWifiConnectedSSId(Context mContext) {
        WifiInfo mWifiInfo = getConnectionInfo(mContext);
        boolean isConnect = isWifiConnected(mContext);
        if (mWifiInfo != null && isConnect) {
            int len = mWifiInfo.getSSID().length();
            if (mWifiInfo.getSSID().startsWith("\"") && mWifiInfo.getSSID().endsWith("\"")) {
                return mWifiInfo.getSSID().substring(1, len - 1);
            } else {
                return mWifiInfo.getSSID();
            }
        }
        return null;
    }

    private WifiInfo getConnectionInfo(Context mContext) {
        WifiManager mManager = (WifiManager) mContext.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        if (mManager != null) {
            return mManager.getConnectionInfo();
        }
        return null;
    }

    private boolean isWifiConnected(Context mContext) {
        ConnectivityManager mConnectivityManager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (mConnectivityManager != null) {
            NetworkInfo mWiFiNetworkInfo = mConnectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
            if (mWiFiNetworkInfo != null) {
                return mWiFiNetworkInfo.isConnected();
            }
        }
        return false;
    }

    /**
     * 获取网络状态
     * @param context 上下文
     * @return int 网络状态
     * {@link #NETWORK_TYPE_INVALID}
     * {@link #NETWORK_TYPE_3G}
     * {@link #NETWORK_TYPE_WIFI}
     */
    public int getNetWorkType(Context context) {
        ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (manager != null) {
            NetworkInfo networkInfo = manager.getActiveNetworkInfo();
            if (networkInfo != null && networkInfo.isConnected()) {
                String type = networkInfo.getTypeName();
                if (type.equalsIgnoreCase("WIFI")) {
                    return NETWORK_TYPE_WIFI;
                } else if (type.equalsIgnoreCase("MOBILE")) {
                    return NETWORK_TYPE_3G;
                }
            }
        }
        return NETWORK_TYPE_INVALID;
    }

    /**
     * 获取当前ip地址
     */
    public String getLocalIpAddress(Context context) {
        try {
            WifiManager mManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
            if (mManager != null) {
                WifiInfo wifiInfo = mManager.getConnectionInfo();
                int i = wifiInfo.getIpAddress();
                return int2ip(i);
            }else {
                return null;
            }
        } catch (Exception ex) {
            return null;
        }
    }

    /**
     * 将ip的整数形式转换成ip形式
     */
    private String int2ip(int ipInt) {
        return (ipInt & 0xFF) + "." +
                ((ipInt >> 8) & 0xFF) + "." +
                ((ipInt >> 16) & 0xFF) + "." +
                ((ipInt >> 24) & 0xFF);
    }

    /**
     * 连接指定Wi-Fi
     */
    public void onConnectWifi(Context context, String SSID, String password, int type){
        WifiManager mWifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        WifiConfiguration configuration = configWifiInfo(mWifiManager, SSID, password, type);
        int netId = configuration.networkId;
        if (mWifiManager!=null) {
            if (netId == -1) {
                netId = mWifiManager.addNetwork(configuration);
            }
            mWifiManager.enableNetwork(netId, true);
        }
    }

    private WifiConfiguration configWifiInfo(WifiManager mWifiManager, String SSID, String password, int type) {
        WifiConfiguration config = null;
        if (mWifiManager != null) {
            List<WifiConfiguration> existingConfigs = mWifiManager.getConfiguredNetworks();
            for (WifiConfiguration existingConfig : existingConfigs) {
                if (existingConfig == null) continue;
                if (existingConfig.SSID.equals("\"" + SSID + "\"")  /*&&  existingConfig.preSharedKey.equals("\""  +  password  +  "\"")*/) {
                    config = existingConfig;
                    break;
                }
            }
        }
        if (config == null) {
            config = new WifiConfiguration();
        }
        config.allowedAuthAlgorithms.clear();
        config.allowedGroupCiphers.clear();
        config.allowedKeyManagement.clear();
        config.allowedPairwiseCiphers.clear();
        config.allowedProtocols.clear();
        config.SSID = "\"" + SSID + "\"";
        // 分为三种情况：0没有密码1用wep加密2用wpa加密
        if (type == 0) {// WIFICIPHER_NOPASSwifiCong.hiddenSSID = false;
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
        } else if (type == 1) {  //  WIFICIPHER_WEP
            config.hiddenSSID = true;
            config.wepKeys[0] = "\"" + password + "\"";
            config.allowedAuthAlgorithms
                    .set(WifiConfiguration.AuthAlgorithm.SHARED);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
            config.allowedGroupCiphers
                    .set(WifiConfiguration.GroupCipher.WEP104);
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
            config.wepTxKeyIndex = 0;
        } else if (type == 2) {   // WIFICIPHER_WPA
            config.preSharedKey = "\"" + password + "\"";
            config.hiddenSSID = true;
            config.allowedAuthAlgorithms
                    .set(WifiConfiguration.AuthAlgorithm.OPEN);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
            config.allowedPairwiseCiphers
                    .set(WifiConfiguration.PairwiseCipher.TKIP);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            config.allowedPairwiseCiphers
                    .set(WifiConfiguration.PairwiseCipher.CCMP);
            config.status = WifiConfiguration.Status.ENABLED;
        }
        return config;
    }
}
